import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'
import router from '@/router'
import qs from 'qs'
// create 创建 axios 实例
const request = axios.create({
  // timeout: 2000
  // baseURL: 'http://edufront.lagou.com'
})

function getBaseUrl (url) {
  if (url.startsWith('/boss')) {
    return 'http://eduboss.lagou.com'
  } else {
    return 'http://edufront.lagou.com'
  }
}

request.interceptors.request.use((config) => {
  // 判断 config.url 的前缀,来进行请求 baseUrl 的设置
  config.baseURL = getBaseUrl(config.url)

  // 同一设置 token 信息
  const { user } = store.state
  if (user && user.access_token) {
    config.headers.Authorization = user.access_token
  }
  return config
})

function redirectLogin () {
  router.push({
    name: 'login',
    query: {
    // router.currentRoute 用于获取当前路由对应的路由信息对象
      redirect: router.currentRoute.fullPath
    }
  })
}
// 存储是否正在更新 Token 的状态
let isRefreshing = false
// 存储 因为等待token 刷新挂起的请求
let requestToken = []

request.interceptors.response.use(function (response) {
  return response
}, function (error) {
  if (error.response) {
    // The request was made and the server responded with a status code
    // that falls out of the range of 2xx
    const { status } = error.response
    var errorMessage = ''
    if (status === 400) {
      errorMessage = '请求参数错误'
    } else if (status === 401) {
      // 1.无token 信息
      if (!store.state.user) {
        redirectLogin()
        // 阻止后续操作，向下抛出错误对象
        return Promise.reject(error)
      }

      // 检测是否以及存在了正在刷新的token的请求
      if (isRefreshing) {
        // 将当前的失败请求 存储在请求列表中
        return requestToken.push(() => {
          // 当前函数调用后，会自动发送本次失败的请求
          request(error.config)
        })
      }
      isRefreshing = true
      // 2. Token 无效（错误Token ，过期Token）
      // 发送请求 获去新的access_token
      return request({
        method: 'POST',
        url: '/front/user/refresh_token',
        data: qs.stringify({
          refreshtoken: store.state.user.refresh_token
        })
      }).then(res => {
        // 检测，是否成功请求到新的 access_token
        // 1. 如果没有请求到新的 access_token，跳转回登录页
        if (res.data.state !== 1) {
          // 清除已经无效的用户信息
          store.commit('setUser', null)
          // 跳转登录页
          redirectLogin()
          // 阻止后续操作，向下抛出错误对象
          return Promise.reject(error)
        }
        // 2. 如果成功，将新的 access_token 更新到容器与本地存储中
        store.commit('setUser', res.data.content)
        // 这时再对之前报 401 的接口重新请求，同时 return
        // - error.config 是之前失败的请求的配置信息
        // - request() 内部已经将原请求的所有功能包含了，无需接收结果返回。
        requestToken.forEach(callback => callback())
        // 清除完毕 requestToken 里面的内容
        requestToken = []
        return request(error.config)
      }).catch(error => {
        console.log(error)
      }).finally(() => {
        isRefreshing = false
      })
    } else if (status === 403) {
      errorMessage = '没有权限，请联系管理员'
    } else if (status === 404) {
      errorMessage = '请求资源不存在'
    } else if (status >= 500) {
      errorMessage = '服务端错误，请联系管理员'
    }
    Message.error(errorMessage)
  } else if (error.request) {
    // The request was made but no response was received
    // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
    // http.ClientRequest in node.js
    Message.error('请求超时请重试')
  } else {
    // Something happened in setting up the request that triggered an Error
    Message.error(error)
  }
})

export default request
